package utils

import (
	"encoding/json"
	"time"
)

// 定义日期格式常量
const (
	DateFormat     = "2006-01-02"          // 仅日期格式
	DateTimeFormat = "2006-01-02 15:04:05" // 日期时间格式
	Timezone       = "Asia/Shanghai"
)

// CustomDate 支持手动指定格式的自定义日期类型
type CustomDate struct {
	time.Time
	ForceDateFormat bool // 强制使用仅日期格式
}

// Now 创建一个当前时间的CustomDate
func Now() CustomDate {
	return FromTime(time.Now())
}

// FromTime 从time.Time创建CustomDate
func FromTime(t time.Time) CustomDate {
	return CustomDate{Time: t}
}

// ForceDate 强制使用仅日期格式（忽略时分秒）
func (c CustomDate) ForceDate() CustomDate {
	c.ForceDateFormat = true
	return c
}

// MarshalJSON 序列化实现
func (c CustomDate) MarshalJSON() ([]byte, error) {
	loc, err := time.LoadLocation(Timezone)
	if err != nil {
		return nil, err
	}

	t := c.Time.In(loc)
	var format string

	// 优先检查是否强制使用日期格式
	if c.ForceDateFormat {
		format = DateFormat
	} else {
		// 否则根据时间是否包含时分秒自动选择
		if t.Hour() == 0 && t.Minute() == 0 && t.Second() == 0 && t.Nanosecond() == 0 {
			format = DateFormat
		} else {
			format = DateTimeFormat
		}
	}
	return json.Marshal(t.Format(format))
}

// UnmarshalJSON 反序列化实现
func (c *CustomDate) UnmarshalJSON(data []byte) error {
	var timeStr string
	if err := json.Unmarshal(data, &timeStr); err != nil {
		return err
	}

	loc, err := time.LoadLocation(Timezone)
	if err != nil {
		return err
	}

	// 尝试解析两种格式
	t, err := time.ParseInLocation(DateTimeFormat, timeStr, loc)
	if err != nil {
		t, err = time.ParseInLocation(DateFormat, timeStr, loc)
		if err != nil {
			return err
		}
	}

	c.Time = t
	return nil
}
